/**********************************************************
File:			Shared.js
Author:			Yongjun Shang
Description:	Shared JavaScript functions
**********************************************************/

var isFieldDirty,
	isFormDirty,
	objectNumber = 0,
	fieldPrefix = "ctl00_WrapperContent_Body_",
	controlWithFocus;

var BrowserDetect = {
    init: function () {
        this.browser = this.searchString(this.dataBrowser) || "An unknown browser";
        this.version = this.searchVersion(navigator.userAgent)
			|| this.searchVersion(navigator.appVersion)
			|| "an unknown version";
        this.OS = this.searchString(this.dataOS) || "an unknown OS";
    },
    searchString: function (data) {
        for (var i = 0; i < data.length; i++) {
            var dataString = data[i].string;
            var dataProp = data[i].prop;
            this.versionSearchString = data[i].versionSearch || data[i].identity;
            if (dataString) {
                if (dataString.indexOf(data[i].subString) != -1)
                    return data[i].identity;
            }
            else if (dataProp)
                return data[i].identity;
        }
    },
    searchVersion: function (dataString) {
        var index = dataString.indexOf(this.versionSearchString);
        if (index == -1) return;
        return parseFloat(dataString.substring(index + this.versionSearchString.length + 1));
    },
    dataBrowser: [
		{
		    string: navigator.userAgent,
		    subString: "Chrome",
		    identity: "Chrome"
		},
		{ string: navigator.userAgent,
		    subString: "OmniWeb",
		    versionSearch: "OmniWeb/",
		    identity: "OmniWeb"
		},
		{
		    string: navigator.vendor,
		    subString: "Apple",
		    identity: "Safari",
		    versionSearch: "Version"
		},
		{
		    prop: window.opera,
		    identity: "Opera",
		    versionSearch: "Version"
		},
		{
		    string: navigator.vendor,
		    subString: "iCab",
		    identity: "iCab"
		},
		{
		    string: navigator.vendor,
		    subString: "KDE",
		    identity: "Konqueror"
		},
		{
		    string: navigator.userAgent,
		    subString: "Firefox",
		    identity: "Firefox"
		},
		{
		    string: navigator.vendor,
		    subString: "Camino",
		    identity: "Camino"
		},
		{		// for newer Netscapes (6+)
		    string: navigator.userAgent,
		    subString: "Netscape",
		    identity: "Netscape"
		},
		{
		    string: navigator.userAgent,
		    subString: "MSIE",
		    identity: "Explorer",
		    versionSearch: "MSIE"
		},
		{
		    string: navigator.userAgent,
		    subString: "Gecko",
		    identity: "Mozilla",
		    versionSearch: "rv"
		},
		{ 		// for older Netscapes (4-)
		    string: navigator.userAgent,
		    subString: "Mozilla",
		    identity: "Netscape",
		    versionSearch: "Mozilla"
		}
	],
    dataOS: [
		{
		    string: navigator.platform,
		    subString: "Win",
		    identity: "Windows"
		},
		{
		    string: navigator.platform,
		    subString: "Mac",
		    identity: "Mac"
		},
		{
		    string: navigator.userAgent,
		    subString: "iPhone",
		    identity: "iPhone/iPod"
		},
		{
		    string: navigator.platform,
		    subString: "Linux",
		    identity: "Linux"
		}
	]

};
BrowserDetect.init();

function setDirty(event)
{
	var keyID = (window.event) ? event.keyCode : event.keyCode;

	if (keyID === 8 || 					// Backspace
		keyID === 32 || 					// Space
		keyID === 46 || 					// Delete
		(keyID >= 48 && keyID <= 90) || 	// 0-9 ; = A-Z
		(keyID >= 96 && keyID <= 111) || // Numpad: 0-9 * + - . /
		(keyID >= 188 && keyID <= 222))		// , . / [ ] ' \ 
	{
		isFieldDirty = isFormDirty = true;
	}
}

function Log(message, object)
{
	alert(message, null, "Error");
}

function HandleException(exception)
{
	try
	{
		Log(exception.get_message(), exception);
	}
	catch (e)
	{
		Log("Unknown client side error. If the problem continues, contact technical support.");
	}

	//throw exception;
}

function HandleError(exception)
{
	HandleException(exception);
}

window.onerror = function(message, url, line)
{
	var error = new Error(message);
	error.message = message;
	error.fileName = url;
	error.lineNumber = line;

	Log(message, error);

	return false;
};

function GetObjectInfo(obj, maxLevels, level)
{
	var str = '', type, msg, x;

	// Start Input Validations
	// Don't touch, we start iterating at level zero
	if (level === null) { level = 0; }

	// At least you want to show the first level
	if (maxLevels === null) { maxLevels = 1; }

	if (maxLevels < 1) { return 'Error: Levels number must be > 0'; }

	// We start with a non null object
	if (obj === null) { return 'Error: Object <b>NULL</b>'; }
	// End Input Validations

	str += "<UL>";

	// Start iterations for all objects in obj
	for (x in obj)
	{
		if (obj[x] !== null)
		{
			try
			{
				// Show "property" and "type property"
				type = typeof (obj[x]);
				str += "<LI>" + x + '</LI> ' + ((obj[x] === null) ? ('null') : "<PRE>" + (obj[x])) + '</PRE>';

				// We keep iterating if this property is an Object, non null
				// and we are inside the required number of levels
				if ((type === 'object') && (obj[x] !== null) && (level + 1 < maxLevels))
				{
					str += GetObjectInfo(obj[x], maxLevels, level + 1);
				}
			}
			catch (err)
			{
				// Is there some properties in obj we can't access? Print it red.
				if (typeof (err) === 'string') { msg = err; }
				else if (err.message) { msg = err.message; }
				else if (err.description) { msg = err.description; }
				else { msg = 'Unknown'; }

				str += '<font color="red">(Error) ' + property + ': ' + msg + '</font>';
			}
		}
	}

	str += "</UL>";

	return str;
}

Date.prototype.toUTCString = function()
{
	var month = this.getUTCMonth() + 1;

	if (month < 10)
	{
		month = "0" + month;
	}

	var date = this.getUTCDate()

	if (date < 10)
	{
		date = "0" + date;
	}

	var year = this.getUTCFullYear();

	var hours = this.getUTCHours();

	if (hours < 10)
	{
		hours = "0" + hours;
	}

	var minutes = this.getUTCMinutes();

	if (minutes < 10)
	{
		minutes = "0" + minutes;
	}

	var seconds = this.getUTCSeconds();

	if (seconds < 10)
	{
		seconds = "0" + seconds;
	}

	return month + "/" + date + "/" + year + " " + hours + ":" + minutes + ":" + seconds + "Z";

}


Date.prototype.toLongTimeString = function()
{
	var hours = this.getHours();

	if (hours < 10)
	{
		hours = "0" + hours;
	}

	var minutes = this.getMinutes();

	if (minutes < 10)
	{
		minutes = "0" + minutes;
	}

	var seconds = this.getSeconds();

	if (seconds < 10)
	{
		seconds = "0" + seconds;
	}

	var milliseconds = this.getMilliseconds();

	if (milliseconds < 10)
	{
		milliseconds = "0" + milliseconds;
	}

	if (milliseconds < 100)
	{
		milliseconds = "0" + milliseconds;
	}

	return hours + ":" + minutes + ":" + seconds + "." + milliseconds;
};


Date.prototype.toShortDateString = function()
{
	var month = this.getMonth() + 1;

	if (month < 10)
	{
		month = "0" + month;
	}

	var date = this.getDate()

	if (date < 10)
	{
		date = "0" + date;
	}

	var year = this.getFullYear();

	return month + "/" + date + "/" + year;

}

Date.prototype.addMonths = function(months)
{
	var temp = new Date(this);

	temp.setMonth(this.getMonth() + months);

	if (temp.getDate() < this.getDate())
	{
		temp.setDate(0);
	}

	return temp;
}

function ParseDate(input)
{
	try
	{
		if (input == null || input == "")
		{
			return null;
		}

		var year = parseInt(input.substring(input.lastIndexOf("/") + 1), 10);
		if (year < 50)
		{
			year = year + 2000;
		}
		if (year < 100)
		{
			year = year + 1900;
		}
		input = input.substring(0, input.lastIndexOf("/") + 1) + year.toString();

		return new Date(input);
	}
	catch (e) { }
}

function ScrollListHeaderDiv(eventArgs)
{
	var headerPanel = eventArgs.headerPanel;
	var contentPanel = eventArgs.contentPanel;

	// Horizontal scroll threshold for the conent panel
	var threshold = eventArgs.threshold;

	// Determine if the scrolling position has exceeded the threshold
	if (contentPanel.scrollLeft() > threshold)
	{
		// Reset the scrolling panel to the threshold
		contentPanel.scrollLeft(threshold);
	}

	// Scroll the header panel horizontally
	headerPanel.scrollLeft(contentPanel.scrollLeft());
}

// Array Remove - By John Resig (MIT Licensed)
Array.prototype.remove = function(from, to)
{
	var rest = this.slice((to || from) + 1 || this.length);
	this.length = from < 0 ? this.length + from : from;
	return this.push.apply(this, rest);
};

Array.prototype.isDotNetDictionary = false;

Array.prototype.toDotNetDictionaryString = function()
{
	if (!this.isDotNetDictionary)
	{
		throw 'The toDotNetDictionaryString method is only supported on arrays where isDotNetDictionary is set to \'true\'';
	}

	//[{ "Key": "'+key+'", "Value": "'+value+'" }]

	var result = '[';

	if (this.length > 0)
	{
		for (var i = 0; i < this.length; i++)
		{
			result += '{ "Key": "' + this[i].Key + '", "Value": "' + this[i].Value;

			if (i === (this.length - 1))
			{
				result += '" }';
			}
			else
			{
				result += '" },';
			}
		}
	}

	result += ']';

	return result;
}

// TODO: add code for Canadian phone numbers
function formatPhoneNumber(phoneNumber)
{
	var phoneRegEx = /^\(\d{3}\) \d{3}-\d{4}$/;
	var result = "";

	if (phoneNumber === undefined || phoneNumber === null)
	{
		return result;
	}

	if (phoneNumber.match(phoneRegEx))
	{
		return phoneNumber;
	}

	if (phoneNumber.length > 10 && !phoneNumber.match(phoneRegEx))
	{
		return phoneNumber;
	}

	if (phoneNumber.length === 10)
	{
		result = "(" + phoneNumber.substr(0, 3) + ") " + phoneNumber.substr(3, 3) + "-" + phoneNumber.substr(6, 4);
	}
	else
	{
		result = phoneNumber;
	}

	return result;
}

// TODO: add code for Canadian postal codes
function formatPostalCode(postalCode)
{
	var postalCodeRegEx = /^(\d{5})(-\d{4})?$/;
	var result = "";

	if (postalCode === undefined)
	{
		return result;
	}

	if (postalCode.match(postalCodeRegEx))
	{
		return postalCode;
	}

	if (postalCode.length > 9 && !postalCode.match(postalCodeRegEx))
	{
		return postalCode;
	}

	if (postalCode.length === 9)
	{
		result = postalCode.substr(0, 5) + "-" + postalCode.substr(5, 4);
	}
	else
	{
		result = postalCode;
	}

	return result;
}

String.prototype.trim = function()
{
	if (this == null || this == "")
	{
		return false;
	}

	return this.replace(/^[\s\xA0]+/, "").replace(/[\s\xA0]+$/, "")
}

String.prototype.startsWith = function(str)
{
	if (this == null || this == "")
	{
		return false;
	}

	return (str != "+" && this.match("^" + str) == str)
}

String.prototype.endsWith = function(str)
{
	if (this == null || this == "")
	{
		return false;
	}

	return (str != "+" && this.match(str + "$") == str)
}

String.prototype.capitalize = function() { return this.replace(/(^|\s)([a-z])/g, function(m, p1, p2) { return p1 + p2.toUpperCase(); }); };

function DecodeHtml(encodedHtml)
{
	return encodedHtml.replace(/&amp;/g, '&').replace(/&lt;/g, '<').replace(/&gt;/g, '>').replace(/&apos;/g, '\'').replace(/&quot;/g, '\"');
}

function IsHtmlEncoded(html)
{
	return html.search(/&amp;/g) != -1 || html.search(/&lt;/g) != -1 || html.search(/&gt;/g) != -1 || html.search(/&apos;/g) != -1 || html.search(/&quot;/g) != -1;
}

function DecodeHtmlIfEncoded(html)
{
	return IsHtmlEncoded(html) ? DecodeHtml(html) : html;
}

$(document).keydown(function(event)
{
	var key = event.keyCode || event.which;

	var allowAction = true;

	if (event.target.type === undefined && key === 8)
	{
		allowAction = false;
	}

	return allowAction;
});

$(document).keypress(function(event)
{
	var key = event.keyCode || event.which;

	var allowAction = true;

	if (event.target.type === undefined && key === 8)
	{
		allowAction = false;
	}

	return allowAction;
});

$(document).ready(function()
{
	// Add the hover and mouse click functions to controls with css class ui-button
	$(".ui-button")
	.hover(
		function()
		{
			$(this).addClass("ui-state-hover");
		},
		function()
		{
			$(this).removeClass("ui-state-hover");
		}
	)
	.mousedown(function()
	{
		$(this).addClass("ui-state-active");
	})
	.mouseup(function()
	{
		$(this).removeClass("ui-state-active");
	})
	.keypress(function(event)
	{
		var key;
		if (window.event)
		{
			key = window.event.keyCode;
		}
		else
		{
			key = event.which;
		}

		return (key !== 8);
	})
	.keydown(function(event)
	{
		var key;
		if (window.event)
		{
			key = window.event.keyCode;
		}
		else
		{
			key = event.which;
		}

		return (key !== 8);
	});

	$(":text").focus(function()
	{
		if (!$(this).attr("readonly"))
		{
			controlWithFocus = $(this);
		}
	})
	.keypress(function(event)
	{
		var key,
			result = false;
		if (window.event)
		{
			key = window.event.keyCode;
		}
		else
		{
			key = event.which;
		}

		if ($(this).attr("readonly") && key === 8)
		{
			result = false;
		}
		else if (key === 13)
		{
			result = false;
		}
		else
		{
			result = true;
		}

		return result;
	})
	.keydown(function(event)
	{
		var key,
			result = false;
		if (window.event)
		{
			key = window.event.keyCode;
		}
		else
		{
			key = event.which;
		}

		if ($(this).attr("readonly") && key === 8)
		{
			result = false;
		}
		else if (key === 13)
		{
			result = false;
		}
		else
		{
			result = true;
		}

		return result;
	});

	$(":checkbox").focus(function()
	{
		if (!$(this).attr("disabled"))
		{
			controlWithFocus = $(this);
		}
	})
	.keypress(function(event)
	{
		var key;
		if (window.event)
		{
			key = window.event.keyCode;
		}
		else
		{
			key = event.which;
		}

		return (key !== 8);
	})
	.keydown(function(event)
	{
		var key;
		if (window.event)
		{
			key = window.event.keyCode;
		}
		else
		{
			key = event.which;
		}

		return (key !== 8);
	});

	$(":radio").focus(function()
	{
		if (!$(this).attr("disabled"))
		{
			controlWithFocus = $(this);
		}
	})
	.keypress(function(event)
	{
		var key;
		if (window.event)
		{
			key = window.event.keyCode;
		}
		else
		{
			key = event.which;
		}

		return (key !== 8);
	})
	.keydown(function(event)
	{
		var key;
		if (window.event)
		{
			key = window.event.keyCode;
		}
		else
		{
			key = event.which;
		}

		return (key !== 8);
	});

	$("select").focus(function()
	{
		if (!$(this).attr("disabled"))
		{
			controlWithFocus = $(this);
		}
	})
	.keypress(function(event)
	{
		var key;
		if (window.event)
		{
			key = window.event.keyCode;
		}
		else
		{
			key = event.which;
		}

		return (key !== 8);
	})
	.keydown(function(event)
	{
		var key;
		if (window.event)
		{
			key = window.event.keyCode;
		}
		else
		{
			key = event.which;
		}

		return (key !== 8);
	});
});


var dialog;

$(function()
{
	dialog = document.createElement("div");
	dialog.id = "global_confirm_alert_dialog";
	$("body").append(dialog);

	$(dialog).dialog({
		bgiframe: true,
		autoOpen: false,
		resizable: false,
		draggable: false,
		stack: false,
		modal: true,
		open: function()
		{
			$(this).next().find(":button")
				.keypress(function(event)
				{
					var key;
					if (window.event)
					{
						key = window.event.keyCode;
					}
					else
					{
						key = event.which;
					}

					return (key !== 8);
				})
				.keydown(function(event)
				{
					var key;
					if (window.event)
					{
						key = window.event.keyCode;
					}
					else
					{
						key = event.which;
					}

					return (key !== 8);
				});
		}
	});
});

window.alert = function(message, callback, title)
{
	$(dialog).html(message);

	if (title == null)
	{
		title = "Shangxu.org";
	}

	$(dialog).dialog("option", {
		title: title,
		buttons: { "Ok": function() { $(this).dialog("close"); if (callback) callback(); } }
	}).dialog("open");
};

window.confirm = function(message, callback, title)
{
	$(dialog).html(message);
	var result

	if (title == null)
	{
		title = "SPX Corporation";
	}

	$(dialog).dialog("option", {
		title: title,
		buttons: {
			No: function(event)
			{
				$(this).dialog("close");
			},
			Yes: function(event)
			{
				$(this).dialog("close");
				callback();
			}
		}
	}).dialog("open");

};


$.fn.extend({
	mask: function(mask)
	{
		return this.setMask({ mask: mask, autoTab: false });
	},
	unmask: function()
	{
		return this.unsetMask();
	}
});



function ReplaceAll(source, stringToFind, stringToReplace)
{
	var temp = source;
	var index = temp.indexOf(stringToFind);
	while (index != -1)
	{
		temp = temp.replace(stringToFind, stringToReplace);
		index = temp.indexOf(stringToFind);
	}
	return temp;
}

function FormatMoney(num) { num = num.toString().replace(/\$|\,/g, ''); if (isNaN(num)) num = "0"; sign = (num == (num = Math.abs(num))); num = Math.floor(num * 100 + 0.50000000001); cents = num % 100; num = Math.floor(num / 100).toString(); if (cents < 10) cents = "0" + cents; for (var i = 0; i < Math.floor((num.length - (1 + i)) / 3); i++) num = num.substring(0, num.length - (4 * i + 3)) + ',' + num.substring(num.length - (4 * i + 3)); return (((sign) ? '' : '-') + '$' + num + '.' + cents); }


function Exception(name, msg)
{
	try
	{
		throw new Error("")
	} catch (e)
	{
		e.stack = e.stack.split("@" + e.fileName + ":").join(":");
		full_stack = e.stack.split("\\n");
		stack = [];
		stack[0] = "Exception: " + name + "(\"" + msg + "\")"
		for (var i = 2; i < full_stack.length - 3; i++)
		{
			entry = full_stack[i];
			entry_detailed = entry.split(":");
			entry_detailed[1] = entry_detailed[1] - 4; // THIS is to
			// mark, that we'll "move" the source 4 lines higher,
			// ... because it's eval code executed. Remove that for
			// clear values.
			if (i == 2) lineNumber = entry_detailed[1];
			stack[i] = entry_detailed.join(":");
		}
		return {
			name: name,
			message: msg,
			stack: stack.join("\\n"),
			lineNumber: lineNumber
		};
	}
}

function IsNumeric(text)
{
    var ValidChars = "0123456789.";
    var dotCount = 0;
	var IsNumber = true;
	var Char;

	for (i = 0; i < text.length && IsNumber == true; i++)
	{
		Char = text.charAt(i);
		if ((i == 0) && (Char == "-")) // check first character for minus sign
		{
			continue;
        }
        if (Char == ".")
        {
            dotCount++;
        }
		if (ValidChars.indexOf(Char) == -1)
		{
			IsNumber = false;
			break;
        }
    }

    return IsNumber && (dotCount <= 1);
}

$(window).resize(function()
{
	if ($('#common-dialog').dialog('isOpen'))
	{
		$('#common-dialog').dialog('option', 'position', 'center');
	}
});

// Because Javascript can't round to save it's life
function round_number(number, dec_places, isReturnString)
{
	//(c) Copyright 2008, Russell Walker, Netshine Software Limited. www.netshinesoftware.com   
	//Version 2.0. Change log:
	//18/12/08 Fixed bug where digits after decimal point greater than 995
	//29/01/09 Added support for negative numbers (symmetrical rounding) and strip white space
	//12/03/09 Fixed bug where first digit is a 9 and needs to be rounded up
	var new_number = '';
	var resultString = '';
	var i = 0; //Just used in loops
	var sign = ""; //If negative, a minus sign will be prefixed to the result
	var precision, coefficient, result;
	precision = Math.abs(parseInt(dec_places)) || 0;
	coefficient = Math.pow(10, precision);

	number = number.toString(); //We need to operate on and return a string, not a number
	number = number.replace(/^\s+|\s+$/g, ''); //Remove any excess white space

	//Do we have a negative number?
	if (number.charCodeAt(0) == 45) //minus sign
	{
		sign = '-';
		number = number.substr(1).replace(/^\s+|\s+$/g, '');
	}

	dec_places = dec_places * 1; //We need an integer
	dec_point_pos = number.lastIndexOf(".");

	//If there is nothing before the decimal point, prefix with a zero
	if (dec_point_pos == 0)
	{
		number = "0" + number;
		dec_point_pos = 1;
	}

	//Has an integer been passed in?
	if (dec_point_pos == -1 || dec_point_pos == number.length - 1)
	{
		if (dec_places > 0)
		{
			new_number = number + ".";
			for (i = 0; i < dec_places; i++)
			{
				new_number += "0";
			}
			if (new_number == 0)
			{
				sign = "";
			}
			
			resultString = sign + new_number;

			if (isReturnString !== undefined && isReturnString !== null && isReturnString === true)
			{
				return resultString;
			}

			// we round because parseFloat adds insignificat decimals that throws our calculations off.
			result = Math.round(parseFloat(resultString) * coefficient) / coefficient;

			return result;
		}
		else
		{
			resultString = sign + number;

			if (isReturnString !== undefined && isReturnString !== null && isReturnString === true)
			{
				return resultString;
			}

			// we round because parseFloat adds insignificat decimals that throws our calculations off.
			result = Math.round(parseFloat(resultString) * coefficient) / coefficient;

			return result;
		}
	}

	//Do we already have the right number of decimal places?
	var existing_places = (number.length - 1) - dec_point_pos;
	if (existing_places == dec_places)
	{
		resultString = sign + number; //If so, just return the input value

		if (isReturnString !== undefined && isReturnString !== null && isReturnString === true)
		{
			return resultString;
		}

		// we round because parseFloat adds insignificat decimals that throws our calculations off.
		result = Math.round(parseFloat(resultString) * coefficient) / coefficient;

		return result;
	}

	//Do we already have less than the number of decimal places we want?
	if (existing_places < dec_places)
	{
		//If so, pad out with zeros
		new_number = number;
		for (i = existing_places; i < dec_places; i++)
		{
			new_number += "0";
		}
		if (new_number == 0)
		{
			sign = "";
		}
		resultString = sign + new_number;

		if (isReturnString !== undefined && isReturnString !== null && isReturnString === true)
		{
			return resultString;
		}

		// we round because parseFloat adds insignificat decimals that throws our calculations off.
		result = Math.round(parseFloat(resultString) * coefficient) / coefficient;

		return result;
	}

	//Work out whether to round up or not
	var end_pos = (dec_point_pos * 1) + dec_places;
	var round_up = false; //Whether or not to round up (add 1 to) the next digit along
	if ((number.charAt(end_pos + 1) * 1) > 4)
	{
		round_up = true;
	}

	//Record each digit in an array for easier manipulation
	var digit_array = new Array();
	for (i = 0; i <= end_pos; i++)
	{
		digit_array[i] = number.charAt(i);
	}

	//Round up the last digit if required, and continue until no more 9's are found
	for (i = digit_array.length - 1; i >= 0; i--)
	{
		if (digit_array[i] == ".")
		{
			continue;
		}
		if (round_up)
		{
			digit_array[i]++;
			if (digit_array[i] < 10)
			{
				break;
			}
		}
		else
		{
			break;
		}
	}

	//Reconstruct the string, converting any 10's to 0's (except for first digit which can stay as a 10)
	for (i = 0; i <= end_pos; i++)
	{
		if (digit_array[i] == "." || digit_array[i] < 10 || i == 0)
		{
			new_number += digit_array[i];
		}
		else
		{
			new_number += "0";
		}
	}

	//If there are no decimal places, we don't need a decimal point
	if (dec_places == 0)
	{
		new_number = new_number.replace(".", "");
	}

	if (new_number == 0)
	{
		sign = "";
	}

	//That should do it!
	resultString = sign + new_number;

	if (isReturnString !== undefined && isReturnString !== null && isReturnString === true)
	{
		return resultString;
	}

	// we round because parseFloat adds insignificat decimals that throws our calculations off.
	result = Math.round(parseFloat(resultString) * coefficient) / coefficient;

	return result;
}

function FormatCurrency(num) {
    num = num.toString().replace(/\$|\,/g, '');
    if (isNaN(num))
        num = "0";
    sign = (num == (num = Math.abs(num)));
    num = Math.floor(num * 100 + 0.50000000001);
    cents = num % 100;
    num = Math.floor(num / 100).toString();
    if (cents < 10)
        cents = "0" + cents;
    for (var i = 0; i < Math.floor((num.length - (1 + i)) / 3); i++)
        num = num.substring(0, num.length - (4 * i + 3)) + ',' +
    num.substring(num.length - (4 * i + 3));
    return (((sign) ? '' : '-') + '$' + num + '.' + cents);
}

function AjaxPostJson(url, paras, successfulCallBack, failedCallBack)
{
	var xmlHttp = undefined;
    if (window.ActiveXObject) {
        try {
            xmlHttp = new ActiveXObject("MSXML2.XMLHTTP");
        } catch (othermicrosoft) {
            try {
                xmlHttp = new ActiveXObject(
                     "Microsoft.XMLHTTP");
            } catch (failed) { }
        }
    }
    if (xmlHttp == undefined && window.XMLHttpRequest) {
        // If IE7, Mozilla, Safari, etc: Use native object 
        xmlHttp = new XMLHttpRequest();
    }
    xmlHttp.open("POST", url, true);
    xmlHttp.setRequestHeader("Content-Type", "application/json");
    xmlHttp.setRequestHeader("Connection", "close");
    xmlHttp.onreadystatechange = function () {
        if (xmlHttp.readyState == 4 && xmlHttp.status == 200) {
            successfulCallBack(xmlHttp.responseText);
        }
        else {
            failedCallBack(xmlHttp.status)                    }
    };
    xmlHttp.send(paras);    
};

$.fn.centerInClient = function(options) {
    /// <summary>Centers the selected items in the browser window. Takes into account scroll position.
    /// Ideally the selected set should only match a single element.
    /// </summary>    
    /// <param name="fn" type="Function">Optional function called when centering is complete. Passed DOM element as parameter</param>    
    /// <param name="forceAbsolute" type="Boolean">if true forces the element to be removed from the document flow 
    ///  and attached to the body element to ensure proper absolute positioning. 
    /// Be aware that this may cause ID hierachy for CSS styles to be affected.
    /// </param>
    /// <returns type="jQuery" />
    var opt = { forceAbsolute: false,
                container: window,    // selector of element to center in
                completeHandler: null
              };
    $.extend(opt, options);
   
    return this.each(function(i) {
        var el = $(this);
        var jWin = $(opt.container);
        var isWin = opt.container == window;

        // force to the top of document to ENSURE that 
        // document absolute positioning is available
        if (opt.forceAbsolute) {
            if (isWin)
                el.remove().appendTo("body");
            else
                el.remove().appendTo(jWin.get(0));
        }

        // have to make absolute
        el.css("position", "absolute");

        // height is off a bit so fudge it
        var heightFudge = isWin ? 2.0 : 1.8;

        var x = (isWin ? jWin.width() : jWin.outerWidth()) / 2 - el.outerWidth() / 2;
        var y = (isWin ? jWin.height() : jWin.outerHeight()) / heightFudge - el.outerHeight() / 2;

        el.css("left", x + jWin.scrollLeft());
        el.css("top", y + jWin.scrollTop());

        // if specified make callback and pass element
        if (opt.completeHandler)
            opt.completeHandler(this);
    });
}


// notify the ScriptManager that the script has finished loading
if (typeof (Sys) !== "undefined") { Sys.Application.notifyScriptLoaded(); }